import os
import sys
import threading
import subprocess
import platform
import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox, filedialog
import urllib.request
import zipfile
import tarfile
import re
import ctypes
import tempfile
import shutil
import queue
import io
import time
import locale
import logging

# 全局变量
ADB_PATH = ""
LOG_PROCESS = None
STOP_LOG_THREAD = False
LOG_QUEUE = queue.Queue()

class ProgressWindow:
    """下载进度窗口"""
    def __init__(self):
        self.window = tk.Toplevel()
        self.window.title("ADB 工具安装")
        self.window.geometry("400x150")
        self.window.resizable(False, False)
        self.window.protocol("WM_DELETE_WINDOW", self.on_closing)
        
        # 让窗口置顶
        self.window.transient()
        self.window.grab_set()
        
        # 设置窗口在屏幕中央
        self.window.update_idletasks()
        width = self.window.winfo_width()
        height = self.window.winfo_height()
        x = (self.window.winfo_screenwidth() // 2) - (width // 2)
        y = (self.window.winfo_screenheight() // 2) - (height // 2)
        self.window.geometry(f'{width}x{height}+{x}+{y}')
        
        # 进度显示
        self.status_label = ttk.Label(self.window, text="准备下载 ADB 工具...", padding=10)
        self.status_label.pack()
        
        self.progress_var = tk.DoubleVar()
        self.progress_bar = ttk.Progressbar(
            self.window, 
            variable=self.progress_var,
            maximum=100,
            length=300,
            mode='determinate'
        )
        self.progress_bar.pack(pady=10)
        
        self.detail_label = ttk.Label(self.window, text="正在初始化...", padding=10)
        self.detail_label.pack()
        
        self.can_close = False
        self.is_cancelled = False
        
        # 立即更新窗口显示
        self.window.update()
    
    def update_progress(self, percentage, status="", detail=""):
        """更新进度条和状态"""
        self.progress_var.set(percentage)
        if status:
            self.status_label.config(text=status)
        if detail:
            self.detail_label.config(text=detail)
        self.window.update()
    
    def on_closing(self):
        """窗口关闭事件处理"""
        if self.can_close:
            self.window.destroy()
        else:
            result = messagebox.askyesno(
                "确认取消",
                "正在下载安装ADB工具，取消将退出程序。\n确定要取消安装吗？"
            )
            if result:
                self.is_cancelled = True
                self.window.quit()
                sys.exit(0)
    
    def close(self):
        """关闭窗口"""
        self.can_close = True
        self.window.destroy()

class AdbManager:
    """管理ADB的检测和使用"""
    
    def __init__(self):
        self.platform = platform.system().lower()
        self.temp_dir = None
        self.adb_dir = None
        self.adb_executable = None
        self.using_system_adb = False
        # 添加程序数据目录
        self.app_data_dir = self.get_app_data_dir()
        
    def get_app_data_dir(self):
        """获取程序数据存储目录"""
        if self.platform == "windows":
            base_dir = os.path.expandvars("%LOCALAPPDATA%")
            app_dir = os.path.join(base_dir, "ADBLogcat")
        else:
            base_dir = os.path.expanduser("~")
            app_dir = os.path.join(base_dir, ".adblogcat")
            
        if not os.path.exists(app_dir):
            os.makedirs(app_dir)
        return app_dir
    
    def get_adb_url(self):
        """获取对应系统的ADB下载链接"""
        if self.platform == "windows":
            return "https://dl.google.com/android/repository/platform-tools-latest-windows.zip"
        elif self.platform == "darwin":
            return "https://dl.google.com/android/repository/platform-tools-latest-darwin.zip"
        elif self.platform == "linux":
            return "https://dl.google.com/android/repository/platform-tools-latest-linux.zip"
        else:
            raise Exception("Unsupported platform")
    
    def check_system_adb(self):
        """检查系统是否已经安装了ADB"""
        try:
            # 检查系统路径中的ADB
            adb_name = "adb.exe" if self.platform == "windows" else "adb"
            result = subprocess.run([adb_name, "version"], 
                                  capture_output=True, text=True, timeout=3)
            
            # 验证确实是ADB
            if "Android Debug Bridge" in result.stdout:
                self.adb_executable = adb_name
                self.using_system_adb = True
                print(f"检测到系统ADB: {adb_name}")
                return True
                
        except (FileNotFoundError, subprocess.TimeoutExpired):
            pass
            
        return False
    
    def download_file(self, url, progress_window):
        """下载文件到临时位置"""
        file_name = url.split('/')[-1]
        file_path = os.path.join(self.temp_dir, file_name)
        
        try:
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
            }
            request = urllib.request.Request(url, headers=headers)
            
            with urllib.request.urlopen(request) as response:
                file_size = int(response.headers.get('Content-Length', 0))
                
                progress_window.update_progress(0, "正在下载 ADB 工具包...")
                
                with open(file_path, 'wb') as out_file:
                    downloaded = 0
                    block_size = 8192
                    
                    while True:
                        buffer = response.read(block_size)
                        if not buffer:
                            break
                        
                        downloaded += len(buffer)
                        out_file.write(buffer)
                        
                        if file_size:
                            progress = int((downloaded / file_size) * 100)
                            detail = f"已下载: {downloaded/1024/1024:.1f}MB / {file_size/1024/1024:.1f}MB"
                            progress_window.update_progress(progress, detail=detail)
                            
                            if progress_window.is_cancelled:
                                raise Exception("用户取消下载")
            
            return file_path
            
        except Exception as e:
            if os.path.exists(file_path):
                try:
                    os.remove(file_path)
                except:
                    pass
            raise Exception(f"下载失败: {str(e)}")
    
    def extract_file(self, file_path, progress_window):
        """解压下载的文件"""
        progress_window.update_progress(0, "正在解压文件...", "请稍候...")
        
        try:
            if file_path.endswith('.zip'):
                with zipfile.ZipFile(file_path, 'r') as zip_ref:
                    total_files = len(zip_ref.filelist)
                    for index, _ in enumerate(zip_ref.filelist, 1):
                        if progress_window.is_cancelled:
                            raise Exception("用户取消安装")
                        progress = int((index / total_files) * 100)
                        progress_window.update_progress(
                            progress,
                            detail=f"正在解压: {index}/{total_files}"
                        )
                        zip_ref.extractall(self.temp_dir)
            
            # 确定解压后的路径
            self.adb_dir = os.path.join(self.temp_dir, "platform-tools")
            
            # 根据系统设置ADB可执行文件
            if self.platform == "windows":
                self.adb_executable = os.path.join(self.adb_dir, "adb.exe")
            else:
                self.adb_executable = os.path.join(self.adb_dir, "adb")
                
            # 在macOS/Linux上添加可执行权限
            if self.platform != "windows" and self.adb_executable:
                os.chmod(self.adb_executable, 0o755)
                
            progress_window.update_progress(100, "解压完成", "正在配置...")
            
        except Exception as e:
            raise Exception(f"解压失败: {str(e)}")
    
    def setup_adb(self):
        """设置ADB环境"""
        progress_window = None
        try:
            # 首先检查系统是否已有ADB
            if self.check_system_adb():
                logging.info("检测到系统ADB可用")
                return True
            
            # 检查是否已经下载过ADB
            stored_adb = os.path.join(self.app_data_dir, "platform-tools", 
                                    "adb.exe" if self.platform == "windows" else "adb")
            if os.path.exists(stored_adb):
                self.adb_executable = stored_adb
                logging.info("使用已下载的ADB")
                if self.verify_adb():
                    return True
            
            # 创建进度窗口
            progress_window = ProgressWindow()
            
            # 创建临时目录
            self.temp_dir = tempfile.mkdtemp(prefix="adb_tool_")
            logging.info(f"创建临时目录: {self.temp_dir}")
            
            # 下载ADB
            url = self.get_adb_url()
            download_path = self.download_file(url, progress_window)
            
            # 解压文件
            self.extract_file(download_path, progress_window)
            
            # 复制到程序数据目录
            platform_tools_dir = os.path.join(self.app_data_dir, "platform-tools")
            if os.path.exists(platform_tools_dir):
                shutil.rmtree(platform_tools_dir)
            shutil.copytree(self.adb_dir, platform_tools_dir)
            self.adb_executable = os.path.join(
                platform_tools_dir,
                "adb.exe" if self.platform == "windows" else "adb"
            )
            
            # 验证安装
            if self.verify_adb():
                progress_window.update_progress(100, "安装完成", "ADB 工具已准备就绪")
                messagebox.showinfo("安装成功", "ADB 工具已成功安装完成！")
                progress_window.close()
                return True
            else:
                raise Exception("ADB 验证失败")
                
        except Exception as e:
            if progress_window:
                progress_window.close()
            error_msg = f"设置ADB环境失败: {str(e)}"
            logging.error(error_msg)
            return False
            
        finally:
            # 清理临时文件
            if self.temp_dir and os.path.exists(self.temp_dir):
                try:
                    shutil.rmtree(self.temp_dir)
                except:
                    pass

    def verify_adb(self):
        """验证ADB是否工作正常"""
        if not self.adb_executable or not os.path.exists(self.adb_executable):
            logging.error(f"ADB可执行文件不存在: {self.adb_executable}")
            return False
            
        try:
            # 添加详细的错误信息
            result = subprocess.run(
                [self.adb_executable, "version"], 
                capture_output=True,
                text=True,
                timeout=10
            )
            
            if result.returncode != 0:
                logging.error(f"ADB验证失败，返回码: {result.returncode}")
                logging.error(f"错误输出: {result.stderr}")
                return False
                
            if "Android Debug Bridge" not in result.stdout:
                logging.error("ADB输出格式不正确")
                logging.error(f"实际输出: {result.stdout}")
                return False
                
            logging.info("ADB验证成功")
            return True
            
        except subprocess.TimeoutExpired:
            logging.error("ADB验证超时")
            return False
        except Exception as e:
            logging.error(f"ADB验证出现异常: {str(e)}")
            return False
    
    def start_adb_server(self):
        """启动ADB服务"""
        try:
            # 如果使用内置ADB，启动时设置为USB模式
            if not self.using_system_adb:
                subprocess.run([self.adb_executable, "usb"], 
                              stdout=subprocess.DEVNULL, 
                              stderr=subprocess.DEVNULL)
                
            # 启动ADB服务
            subprocess.run([self.adb_executable, "start-server"], 
                          stdout=subprocess.DEVNULL, 
                          stderr=subprocess.DEVNULL)
            print("ADB服务已启动")
            return True
        except Exception as e:
            print(f"启动ADB服务失败: {e}")
            return False
    
    def cleanup(self):
        """清理临时文件（保留程序数据目录中的ADB）"""
        if self.temp_dir and os.path.exists(self.temp_dir):
            try:
                shutil.rmtree(self.temp_dir)
                print("已清理临时目录")
            except Exception as e:
                print(f"清理失败: {e}")


class LogcatApp:
    """GUI应用程序"""
    
    def __init__(self, root, adb_executable):
        self.root = root
        self.root.title("ADB Logcat 抓包工具")
        self.root.geometry("800x600")
        self.adb_executable = adb_executable
        self.log_thread = None
        self.devices = []
        
        # 设置UI
        self.setup_ui()
        
        # 检测连接的设备
        self.update_device_list()
    
    def setup_ui(self):
        """设置用户界面"""
        # 创建主框架
        main_frame = ttk.Frame(self.root, padding=10)
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 设备选择部分
        device_frame = ttk.LabelFrame(main_frame, text="设备选择", padding=10)
        device_frame.pack(fill=tk.X, pady=5)
        
        self.device_var = tk.StringVar()
        self.device_combobox = ttk.Combobox(device_frame, textvariable=self.device_var, state="readonly")
        self.device_combobox.pack(fill=tk.X, padx=5, pady=2)
        
        refresh_btn = ttk.Button(device_frame, text="刷新设备列表", command=self.update_device_list)
        refresh_btn.pack(side=tk.RIGHT, padx=5)
        
        # 过滤选项部分
        filter_frame = ttk.LabelFrame(main_frame, text="日志过滤 (可选)", padding=10)
        filter_frame.pack(fill=tk.X, pady=5)
        
        # 关键字输入
        keyword_label = ttk.Label(filter_frame, text="关键字(可选):")
        keyword_label.grid(row=0, column=0, sticky=tk.W, padx=5)
        
        self.keyword_var = tk.StringVar()
        self.keyword_entry = ttk.Entry(filter_frame, textvariable=self.keyword_var)
        self.keyword_entry.grid(row=0, column=1, sticky=tk.W+tk.E, padx=5, pady=2)
        
        # 多关键字选项
        multi_keywords_label = ttk.Label(filter_frame, text="多个关键字(以分号隔开):")
        multi_keywords_label.grid(row=1, column=0, sticky=tk.W, padx=5)
        
        self.multi_keywords_var = tk.StringVar()
        self.multi_keywords_entry = ttk.Entry(filter_frame, textvariable=self.multi_keywords_var)
        self.multi_keywords_entry.grid(row=1, column=1, sticky=tk.W+tk.E, padx=5, pady=2)
        
        # 正则表达式选项
        self.regex_var = tk.BooleanVar()
        regex_check = ttk.Checkbutton(filter_frame, text="使用正则表达式", variable=self.regex_var)
        regex_check.grid(row=2, column=0, columnspan=2, sticky=tk.W, padx=5, pady=2)
        
        # 日志级别选择
        level_label = ttk.Label(filter_frame, text="日志级别:")
        level_label.grid(row=3, column=0, sticky=tk.W, padx=5)
        
        self.level_var = tk.StringVar(value="V (全部)")  # 默认显示所有日志
        levels = ["V (全部)", "D (调试)", "I (信息)", "W (警告)", "E (错误)", "F (致命错误)", "S (静默)"]
        self.level_combobox = ttk.Combobox(filter_frame, textvariable=self.level_var, values=levels, state="readonly")
        self.level_combobox.grid(row=3, column=1, sticky=tk.W+tk.E, padx=5, pady=2)
        
        # 标签过滤
        tag_label = ttk.Label(filter_frame, text="标签(可选):")
        tag_label.grid(row=4, column=0, sticky=tk.W, padx=5)
        
        # 常用标签列表，可根据实际需求扩展
        common_tags = [
            "",                # 空标签（不筛选标签）
            "ActivityManager", # 活动管理器，系统组件
            "System.out",      # 标准输出，通常是Java的System.out.println
            "AndroidRuntime",  # Android运行时相关日志
            "art",             # Android Runtime（ART）虚拟机日志
            "dalvikvm",        # Dalvik虚拟机日志（老版本Android）
            "ViewRootImpl",    # 界面根视图相关日志
            "WindowManager",   # 窗口管理器相关日志
            "InputMethodManager", # 输入法管理器相关日志
            "WifiManager",     # WiFi管理器相关日志
            "BluetoothAdapter" # 蓝牙适配器相关日志
        ]
        self.tag_var = tk.StringVar()
        self.tag_combobox = ttk.Combobox(filter_frame, textvariable=self.tag_var, values=common_tags, state="normal")
        self.tag_combobox.grid(row=4, column=1, sticky=tk.W+tk.E, padx=5, pady=2)
        self.tag_combobox.set("")  # 默认空
        
        # 按钮控制部分
        button_frame = ttk.Frame(main_frame, padding=5)
        button_frame.pack(fill=tk.X, pady=10)
        
        self.start_button = ttk.Button(button_frame, text="开始抓包", command=self.start_logcat)
        self.start_button.pack(side=tk.LEFT, padx=5)
        
        self.stop_button = ttk.Button(button_frame, text="停止抓包", state=tk.DISABLED, command=self.stop_logcat)
        self.stop_button.pack(side=tk.LEFT, padx=5)
        
        self.clear_button = ttk.Button(button_frame, text="清空控制台", command=self.clear_log)
        self.clear_button.pack(side=tk.LEFT, padx=5)
        
        self.save_button = ttk.Button(button_frame, text="保存日志", command=self.save_log)
        self.save_button.pack(side=tk.RIGHT, padx=5)
        
        # 新增：清除历史日志按钮
        self.clear_history_button = ttk.Button(button_frame, text="清除历史日志", command=self.clear_log_history)
        self.clear_history_button.pack(side=tk.RIGHT, padx=5)
        
        # 日志显示区域
        log_frame = ttk.LabelFrame(main_frame, text="日志输出", padding=10)
        log_frame.pack(fill=tk.BOTH, expand=True, pady=5)
        
        self.log_text = scrolledtext.ScrolledText(log_frame, wrap=tk.WORD)
        self.log_text.pack(fill=tk.BOTH, expand=True)
        self.log_text.insert(tk.END, "提示：可以输入关键字进行过滤，也可以留空抓取所有日志\n\n")
        
        # 状态栏
        self.status_var = tk.StringVar()
        self.status_var.set("就绪")
        status_bar = ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W)
        status_bar.pack(side=tk.BOTTOM, fill=tk.X)
    
    def update_device_list(self):
        """更新设备列表"""
        self.devices = []
        self.device_combobox.set('')
        
        if not self.adb_executable:
            self.status_var.set("ADB未正确配置")
            return
            
        try:
            # 使用二进制流防止编码问题
            result = subprocess.run([self.adb_executable, "devices"], 
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   timeout=10)
            
            # 检测并处理编码
            detected_encoding = self.detect_encoding(result.stdout) or 'utf-8'
            
            # 尝试多种方式解码输出
            try:
                output = result.stdout.decode(detected_encoding, errors='replace')
            except UnicodeDecodeError:
                # 如果首选编码失败，尝试其他常见编码
                try:
                    output = result.stdout.decode('utf-8', errors='replace')
                except:
                    output = result.stdout.decode('latin-1', errors='replace')
            
            # 解析设备列表
            lines = output.strip().split('\n')
            for line in lines[1:]:
                if line and "device" in line:
                    device_id = line.split('\t')[0]
                    self.devices.append(device_id)
            
            if self.devices:
                self.device_combobox['values'] = self.devices
                self.device_combobox.current(0)
                self.status_var.set(f"找到 {len(self.devices)} 个设备")
            else:
                self.status_var.set("未检测到设备，请连接设备后刷新")
                
        except Exception as e:
            self.status_var.set(f"设备检测失败: {str(e)}")
    
    def detect_encoding(self, data):
        """尝试检测字节数据的编码"""
        try:
            import chardet
            result = chardet.detect(data)
            return result['encoding'] if result['encoding'] else 'utf-8'
        except ImportError:
            # 回退到系统编码
            return locale.getpreferredencoding(False) or 'utf-8'
    
    def build_adb_command(self):
        """构建ADB日志命令"""
        if not self.devices:
            raise Exception("没有可用的设备")
            
        device_id = self.device_combobox.get()
        level_map = {
            "V (全部)": "V",
            "D (调试)": "D",
            "I (信息)": "I",
            "W (警告)": "W",
            "E (错误)": "E",
            "F (致命错误)": "F",
            "S (静默)": "S"
        }
        level = level_map[self.level_var.get()]
        cmd = [self.adb_executable]
        
        if device_id:
            cmd.extend(["-s", device_id])
            
        cmd.append("logcat")
        cmd.append("-v")
        cmd.append("time")
        cmd.append(f"*:{level}")
        
        # 添加标签过滤
        tag = self.tag_var.get().strip()
        if tag:
            cmd.append(f"{tag}:{level}")
            
        return cmd
    
    def match_keywords(self, line):
        """检查行是否匹配任意关键字"""
        # 收集所有关键字
        keywords = []
        if self.keyword_var.get().strip():
            keywords.append(self.keyword_var.get().strip())
        if self.multi_keywords_var.get().strip():
            keywords.extend([k.strip() for k in self.multi_keywords_var.get().split(";") if k.strip()])
            
        # 如果没有关键字，显示所有行
        if not keywords:
            return True
            
        if self.regex_var.get():
            # 使用正则表达式匹配
            try:
                for keyword in keywords:
                    if re.search(keyword, line, re.IGNORECASE):
                        return True
                return False
            except re.error:
                # 正则表达式错误时按普通文本处理
                return any(keyword.lower() in line.lower() for keyword in keywords)
        else:
            # 使用普通文本匹配
            return any(keyword.lower() in line.lower() for keyword in keywords)
    
    def start_logcat(self):
        """开始抓取日志"""
        global STOP_LOG_THREAD
        
        if not self.devices:
            messagebox.showwarning("无设备", "没有可用的设备，请连接设备后刷新")
            return
        
        # 新增：抓包前清除设备端日志缓冲区
        try:
            device_id = self.device_combobox.get()
            clear_cmd = [self.adb_executable]
            if device_id:
                clear_cmd.extend(["-s", device_id])
            clear_cmd.append("logcat")
            clear_cmd.append("-c")
            subprocess.run(clear_cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        except Exception as e:
            messagebox.showwarning("警告", f"清除设备日志缓冲区失败: {str(e)}")
        
        # 重置状态
        if self.log_thread and self.log_thread.is_alive():
            self.stop_logcat()
            
        STOP_LOG_THREAD = False
        
        # 构建命令
        try:
            cmd = self.build_adb_command()
        except Exception as e:
            messagebox.showerror("错误", str(e))
            return
            
        # 更新UI状态
        self.start_button.config(state=tk.DISABLED)
        self.stop_button.config(state=tk.NORMAL)
        self.status_var.set("正在抓取日志...")
        
        # 启动日志抓取线程
        self.log_thread = threading.Thread(target=self.capture_logs, args=(cmd,))
        self.log_thread.daemon = True
        self.log_thread.start()
        
        # 启动日志显示线程
        self.display_thread = threading.Thread(target=self.display_logs)
        self.display_thread.daemon = True
        self.display_thread.start()
    
    def capture_logs(self, cmd):
        """在线程中抓取日志"""
        global LOG_PROCESS
        try:
            LOG_PROCESS = subprocess.Popen(
                cmd,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT
            )
            while not STOP_LOG_THREAD:
                try:
                    line = None
                    try:
                        line_bytes = LOG_PROCESS.stdout.readline()
                        if not line_bytes:
                            # 检查进程是否意外终止（如设备断开）
                            if LOG_PROCESS.poll() is not None:
                                LOG_QUEUE.put("[设备可能已断开或日志进程已结束]\n")
                                break
                            time.sleep(0.1)
                            continue
                    except Exception as e:
                        LOG_QUEUE.put(f"读取错误: {str(e)}\n")
                        break
                    try:
                        line = line_bytes.decode('utf-8', errors='replace')
                    except UnicodeDecodeError:
                        try:
                            line = line_bytes.decode('gbk', errors='replace')
                        except:
                            line = line_bytes.decode('latin-1', errors='replace')
                    if line and self.match_keywords(line):
                        LOG_QUEUE.put(line)
                except Exception as e:
                    LOG_QUEUE.put(f"处理错误: {str(e)}\n")
        except Exception as e:
            LOG_QUEUE.put(f"错误: {str(e)}\n")
        finally:
            if LOG_PROCESS and LOG_PROCESS.poll() is None:
                LOG_PROCESS.terminate()
                LOG_PROCESS = None
            LOG_QUEUE.put(None)

    def display_logs(self):
        """在文本框中显示日志"""
        device_disconnected = False
        while not STOP_LOG_THREAD:
            try:
                line = LOG_QUEUE.get(timeout=0.1)
                if line is None:
                    break
                if "[设备可能已断开" in line and not device_disconnected:
                    device_disconnected = True
                    self.status_var.set("设备已断开，日志抓取已停止")
                    self.start_button.config(state=tk.NORMAL)
                    self.stop_button.config(state=tk.DISABLED)
                    messagebox.showerror("设备断开", "设备已断开连接，日志抓取已停止。请重新连接设备后再试。")
                    self.stop_logcat()
                    break
                self.log_text.insert(tk.END, line)
                self.log_text.see(tk.END)
                self.root.update_idletasks()
            except queue.Empty:
                pass
        if not device_disconnected:
            self.status_var.set("日志抓取已停止")
            self.start_button.config(state=tk.NORMAL)
            self.stop_button.config(state=tk.DISABLED)
    
    def stop_logcat(self):
        """停止抓取日志"""
        global STOP_LOG_THREAD, LOG_PROCESS
        STOP_LOG_THREAD = True
        
        if LOG_PROCESS and LOG_PROCESS.poll() is None:
            LOG_PROCESS.terminate()
            LOG_PROCESS = None
        
        self.status_var.set("正在停止日志抓取...")
    
    def clear_log(self):
        """清空日志显示"""
        self.log_text.delete(1.0, tk.END)
    
    def clear_log_history(self):
        """清除历史日志（彻底清空日志队列和显示）"""
        global LOG_QUEUE
        self.clear_log()  # 清空显示
        # 清空队列
        while not LOG_QUEUE.empty():
            try:
                LOG_QUEUE.get_nowait()
            except queue.Empty:
                break
        self.status_var.set("历史日志已清除")
    
    def save_log(self):
        """保存日志到文件（使用UTF-8编码）"""
        log_content = self.log_text.get(1.0, tk.END)
        if not log_content.strip() or log_content.strip() == "提示：可以输入关键字进行过滤，也可以留空抓取所有日志":
            messagebox.showwarning("空日志", "没有可保存的日志内容")
            return
            
        file_path = filedialog.asksaveasfilename(
            defaultextension=".log",
            filetypes=[("日志文件", "*.log"), ("所有文件", "*.*")]
        )
        
        if file_path:
            try:
                # 使用UTF-8编码保存文件
                with open(file_path, "w", encoding="utf-8") as f:
                    f.write(log_content)
                self.status_var.set(f"日志已保存到: {file_path}")
            except Exception as e:
                messagebox.showerror("保存失败", f"无法保存文件: {str(e)}")

def setup_dpi_awareness():
    """在Windows系统上设置DPI感知以提高显示效果"""
    if platform.system() == "Windows":
        try:
            ctypes.windll.shcore.SetProcessDpiAwareness(1)
        except:
            pass

def main():
    """主函数"""
    global ADB_PATH
    
    # 添加日志文件记录
    logging.basicConfig(
        filename='adb_logcat.log',
        level=logging.DEBUG,
        format='%(asctime)s - %(levelname)s - %(message)s'
    )
    
    logging.info("启动ADB Logcat抓包工具...")
    print("启动ADB Logcat抓包工具...")
    
    setup_dpi_awareness()
    
    # 设置ADB环境
    adb_manager = AdbManager()
    
    try:
        # 先尝试系统ADB
        if adb_manager.check_system_adb():
            ADB_PATH = adb_manager.adb_executable
            print("使用系统ADB")
        else:
            # 如果系统没有ADB，自动下载并配置
            print("系统未检测到ADB，正在自动下载配置...")
            messagebox.showinfo("配置提示", "首次使用需要下载ADB工具")
            
            if adb_manager.setup_adb():
                ADB_PATH = adb_manager.adb_executable
                print("ADB自动配置成功")
            else:
                raise Exception("无法自动配置ADB环境")
        
        # 启动GUI
        root = tk.Tk()
        app = LogcatApp(root, ADB_PATH)
        root.mainloop()
        
    except Exception as e:
        error_msg = f"错误: {str(e)}\n如果问题持续，请检查网络连接或联系开发者。"
        messagebox.showerror("启动失败", error_msg)
        logging.error(error_msg)
    finally:
        # 清理临时资源
        if LOG_PROCESS and LOG_PROCESS.poll() is None:
            LOG_PROCESS.terminate()
        adb_manager.cleanup()

if __name__ == "__main__":
    main()